home *** CD-ROM | disk | FTP | other *** search
- Subject: v12i009: Cake, a make replacement, Part03/09
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: Zoltan Somogyi <zs@munnari.oz>
- Posting-number: Volume 12, Issue 9
- Archive-name: cake/part03
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # list.c
- # main.c
- # make.c
- # mem.c
- # pat.c
- # print.c
- # proc.c
- # sym.c
- # sys.c
- # table.c
- # test.c
- # trail.c
- # This archive created: Wed Oct 14 21:10:02 1987
- export PATH; PATH=/bin:/usr/bin:$PATH
- echo shar: "extracting 'list.c'" '(2669 characters)'
- if test -f 'list.c'
- then
- echo shar: "will not over-write existing file 'list.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'list.c'
- X/*
- X** Linked list module.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/list.c,v 1.14 86/07/19 12:23:15 zs Exp $";
- X
- X#include "cake.h"
- X
- X/*
- X** Make an empty list.
- X*/
- X
- XList *
- Xmakelist0()
- X{
- X reg List *list;
- X
- X list = make(List);
- X ldata(list) = (Cast) 0;
- X next(list) = list;
- X prev(list) = list;
- X
- X return list;
- X}
- X
- X/*
- X** Make a list with the argument is its only element.
- X*/
- X
- XList *
- X_makelist(data)
- Xreg Cast data;
- X{
- X return addhead(makelist0(), data);
- X}
- X
- X/*
- X** Add some data to the head of a list.
- X*/
- X
- XList *
- X_addhead(list, data)
- Xreg List *list;
- Xreg Cast data;
- X{
- X reg List *item;
- X
- X if (list == NULL)
- X list = makelist0();
- X
- X item = make(List);
- X ldata(item) = data;
- X ldata(list) = (Cast) ((int) ldata(list) + 1);
- X
- X /* item's pointers */
- X next(item) = next(list);
- X prev(item) = list;
- X /* neighbours' pointers */
- X next(prev(item)) = item;
- X prev(next(item)) = item;
- X
- X return list;
- X}
- X
- X/*
- X** Add some data to the tail of a list.
- X*/
- X
- XList *
- X_addtail(list, data)
- Xreg List *list;
- Xreg Cast data;
- X{
- X reg List *item;
- X
- X if (list == NULL)
- X list = makelist0();
- X
- X item = make(List);
- X ldata(item) = data;
- X ldata(list) = (Cast) ((int) ldata(list) + 1);
- X
- X /* item's pointers */
- X next(item) = list;
- X prev(item) = prev(list);
- X /* neighbours' pointers */
- X next(prev(item)) = item;
- X prev(next(item)) = item;
- X
- X return list;
- X}
- X
- X/*
- X** Destructively append list2 to list1. Since the header of
- X** list2 is not meaningful after the operation, it is freed.
- X*/
- X
- XList *
- Xaddlist(list1, list2)
- Xreg List *list1;
- Xreg List *list2;
- X{
- X if (list1 == NULL)
- X list1 = makelist0();
- X
- X if (list2 == NULL)
- X list2 = makelist0();
- X
- X if (length(list2) > 0)
- X {
- X if (length(list1) == 0)
- X {
- X ldata(list1) = ldata(list2);
- X /* pointers from header */
- X next(list1) = next(list2);
- X prev(list1) = prev(list2);
- X /* pointers to header */
- X prev(next(list1)) = list1;
- X next(prev(list1)) = list1;
- X }
- X else
- X {
- X ldata(list1) = (Cast) ((int) ldata(list1) + (int) ldata(list2));
- X /* end of list 1 to start of list 2 */
- X next(prev(list1)) = next(list2);
- X prev(next(list2)) = prev(list1);
- X /* end of list 2 to start of list 1 */
- X next(prev(list2)) = list1;
- X prev(list1) = prev(list2);
- X }
- X }
- X
- X oldmem((Cast) list2);
- X return list1;
- X}
- X
- X/*
- X** Return the length of a given list.
- X*/
- X
- Xint
- Xlength(list)
- Xreg List *list;
- X{
- X if (list == NULL)
- X return 0;
- X
- X return (int) ldata(list);
- X}
- X
- X/*
- X** Delete an item from its linked list, and free the node.
- X*/
- X
- Xdelete(list, item)
- Xreg List *list;
- Xreg List *item;
- X{
- X if (list == NULL)
- X return;
- X
- X if (item == NULL)
- X return;
- X
- X ldata(list) = (Cast) ((int) ldata(list) - 1);
- X next(prev(item)) = next(item);
- X prev(next(item)) = prev(item);
- X
- X oldmem((Cast) item);
- X}
- SHAR_EOF
- if test 2669 -ne "`wc -c < 'list.c'`"
- then
- echo shar: "error transmitting 'list.c'" '(should have been 2669 characters)'
- fi
- fi
- echo shar: "extracting 'main.c'" '(9780 characters)'
- if test -f 'main.c'
- then
- echo shar: "will not over-write existing file 'main.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'main.c'
- X/*
- X** Cake main file.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/main.c,v 1.15 87/10/05 20:14:53 zs Exp $";
- X
- X#include "cake.h"
- X#include <pwd.h>
- X#include <signal.h>
- X#include <sys/stat.h>
- X
- Xtypedef struct passwd Pwent;
- Xtypedef struct stat Stat;
- X
- Xint Gflag = FALSE;
- Xint Lflag = FALSE;
- Xint Rflag = FALSE;
- Xint Xflag = FALSE;
- Xint Zflag = FALSE;
- Xint bflag = FALSE;
- Xint cflag = FALSE;
- Xint dflag = FALSE;
- Xint gflag = FALSE;
- Xint iflag = FALSE;
- Xint kflag = TRUE;
- Xint nflag = FALSE;
- Xint qflag = FALSE;
- Xint rflag = FALSE;
- Xint sflag = FALSE;
- Xint tflag = FALSE;
- Xint vflag = FALSE;
- Xint wflag = FALSE;
- Xint xflag = FALSE;
- Xint zflag = FALSE;
- X
- Xchar *cakefile = NULL;
- Xchar *shellfile[2] = { SYSTEM_CMD, SCRIPT_CMD };
- Xchar *metachars = METACHARS;
- Xint maxprocs = 1;
- XList *active_procs;
- Xchar scratchbuf[128];
- X
- Xint cakedebug = FALSE;
- Xint entrydebug = FALSE;
- Xint patdebug = FALSE;
- Xint lexdebug = FALSE;
- X
- Xchar cakeflagbuf[MAXSIZE];
- Xchar *cppargv[MAXARGS];
- Xint cppargc = 0;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X extern cake_abort(), cake_finish();
- X extern int parse_args(), process_args();
- X extern Node *chase();
- X extern char *getenv();
- X extern char *dir_setup();
- X extern Pwent *getpwuid();
- X extern int geteuid();
- X extern FILE *cake_popen();
- X extern FILE *yyin;
- X extern int yydebug;
- X Stat statbuf;
- X int envc;
- X char *envv[MAXARGS];
- X reg Pwent *pwent;
- X reg char *envstr;
- X reg int status;
- X reg Node *rootnode;
- X
- X signal(SIGINT, cake_finish);
- X signal(SIGQUIT, cake_finish);
- X signal(SIGILL, cake_abort);
- X signal(SIGTRAP, cake_abort);
- X signal(SIGIOT, cake_abort);
- X signal(SIGEMT, cake_abort);
- X signal(SIGFPE, cake_abort);
- X signal(SIGBUS, cake_abort);
- X signal(SIGSEGV, cake_abort);
- X signal(SIGSYS, cake_abort);
- X signal(SIGPIPE, cake_abort);
- X signal(SIGALRM, cake_abort);
- X
- X yydebug = FALSE;
- X active_procs = makelist0();
- X
- X if (rindex(argv[0], 'f') != NULL
- X && streq(rindex(argv[0], 'f'), "fake"))
- X cakedebug = TRUE;
- X
- X init_sym();
- X cppargv[cppargc++] = new_name(CPP);
- X strcpy(cakeflagbuf, "-DCAKEFLAGS=");
- X
- X if ((envstr = getenv("CAKE")) != NULL)
- X {
- X envc = parse_args(envstr, envv);
- X process_args(envv, &envc, 0);
- X if (envc > 0)
- X fprintf(stderr, "cake: non-options in environment ignored\n");
- X }
- X
- X argv += process_args(argv, &argc, 1);
- X
- X#ifdef CAKEDEBUG
- X if (cakedebug || entrydebug || patdebug || lexdebug)
- X setlinebuf(stdout);
- X#endif
- X
- X if (cakefile == NULL)
- X {
- X if (stat("cakefile", &statbuf) == 0)
- X cakefile = "cakefile";
- X or (stat("Cakefile", &statbuf) == 0)
- X cakefile = "Cakefile";
- X or (stat("recipe", &statbuf) == 0)
- X cakefile = "recipe";
- X or (stat("Recipe", &statbuf) == 0)
- X cakefile = "Recipe";
- X else
- X {
- X fprintf(stderr, "cake: cannot locate a cakefile\n");
- X exit(1);
- X }
- X }
- X
- X if (gflag)
- X cakefile = dir_setup(cakefile);
- X
- X pwent = getpwuid(geteuid());
- X strcpy(scratchbuf, "-I");
- X strcat(scratchbuf, pwent->pw_dir);
- X strcat(scratchbuf, ULIB);
- X cppargv[cppargc++] = new_name(scratchbuf);
- X strcpy(scratchbuf, "-I");
- X strcat(scratchbuf, SLIB);
- X cppargv[cppargc++] = new_name(scratchbuf);
- X cppargv[cppargc++] = cakeflagbuf;
- X cppargv[cppargc++] = cakefile;
- X cppargv[cppargc] = NULL;
- X
- X if (cakedebug)
- X {
- X reg int i;
- X
- X for (i = 0; i < cppargc; i++)
- X printf("%s\n", cppargv[i]);
- X }
- X
- X if ((yyin = cake_popen(cppargv, "r")) == NULL)
- X {
- X fprintf(stderr, "cake: cannot open cpp filter\n");
- X exit(1);
- X }
- X
- X if (Zflag)
- X {
- X reg int c;
- X
- X while ((c = getc(yyin)) != EOF)
- X putchar(c);
- X
- X cake_pclose(yyin);
- X exit(0);
- X }
- X
- X yyinit();
- X init_entry();
- X if (yyparse())
- X {
- X fprintf(stderr, "cake: cannot parse %s\n", cakefile);
- X exit(1);
- X }
- X
- X shell_setup(shellfile[0], 0);
- X shell_setup(shellfile[1], 1);
- X meta_setup(metachars);
- X
- X cake_pclose(yyin);
- X dir_start();
- X prep_entries();
- X final_entry(argc, argv);
- X
- X rootnode = chase(CHASEROOT, 0, (Entry *) NULL);
- X
- X if (! qflag)
- X execute(rootnode);
- X
- X dir_finish();
- X cleanup();
- X#ifdef STATS_FILE
- X statistics();
- X#endif
- X
- X status = (off_node(rootnode, nf_ERR) && is_ok(rootnode))? 0: 1;
- X cdebug("exit status %d\n", status);
- X exit(status);
- X}
- X
- Xint
- Xprocess_args(vector, count, base)
- Xreg char **vector;
- Xreg int *count;
- Xreg int base;
- X{
- X reg int i, j;
- X
- X j = 0;
- X cdebug("process args:");
- X while (*count > base && vector[base][0] == '-')
- X {
- X putflag(base, vector[base]);
- X
- X for (i = 1; vector[base][i] != '\0'; i++)
- X {
- X switch (vector[base][i])
- X {
- X
- X#ifdef CAKEDEBUG
- X when 'C': cdebug(" -C");
- X cakedebug = ! cakedebug;
- X
- X when 'E': cdebug(" -E");
- X entrydebug = ! entrydebug;
- X
- X when 'P': cdebug(" -P");
- X patdebug = ! patdebug;
- X
- X when 'W': cdebug(" -W");
- X lexdebug = TRUE;
- X
- X when 'Y': cdebug(" -Y");
- X yydebug = TRUE;
- X#endif
- X when 'G': cdebug(" -G");
- X Gflag = TRUE;
- X
- X when 'L': cdebug(" -L");
- X Lflag = TRUE;
- X
- X when 'R': cdebug(" -R");
- X Rflag = TRUE;
- X
- X when 'X': cdebug(" -X");
- X Xflag = TRUE;
- X
- X when 'Z': cdebug(" -Z");
- X Zflag = TRUE;
- X
- X when 'a': cdebug(" -a");
- X kflag = FALSE;
- X
- X when 'b': cdebug(" -b");
- X bflag = TRUE;
- X
- X when 'c': cdebug(" -c");
- X cflag = TRUE;
- X
- X when 'd': cdebug(" -d");
- X dflag = TRUE;
- X
- X when 'g': cdebug(" -g");
- X gflag = TRUE;
- X
- X when 'i': cdebug(" -i");
- X iflag = TRUE;
- X
- X when 'k': cdebug(" -k");
- X kflag = TRUE;
- X
- X when 'n': cdebug(" -n");
- X nflag = TRUE;
- X tflag = FALSE;
- X qflag = FALSE;
- X
- X when 'q': cdebug(" -q");
- X qflag = TRUE;
- X nflag = FALSE;
- X tflag = FALSE;
- X
- X when 'r': cdebug(" -r");
- X rflag = TRUE;
- X
- X when 's': cdebug(" -s");
- X sflag = TRUE;
- X
- X when 't': cdebug(" -t");
- X tflag = TRUE;
- X nflag = FALSE;
- X qflag = FALSE;
- X
- X when 'v': cdebug(" -v");
- X vflag = TRUE;
- X
- X when 'w': cdebug(" -w");
- X wflag = TRUE;
- X
- X when 'x': cdebug(" -x");
- X xflag = TRUE;
- X
- X when 'z': cdebug(" -z");
- X zflag = TRUE;
- X
- X when 'D':
- X case 'I':
- X case 'U': if (i != 1)
- X usage();
- X
- X cdebug(" %s", vector[base]);
- X cppargv[cppargc++] = new_name(vector[base]);
- X goto nextword;
- X
- X when 'N': putflag(base, vector[base+1]);
- X sscanf(vector[base+1], "%d", &maxprocs);
- X if (vector[base][i+1] != '\0')
- X usage();
- X
- X cdebug(" -N %d", maxprocs);
- X (*count)--;
- X vector++, j++;
- X goto nextword;
- X
- X when 'S': putflag(base, vector[base+1]);
- X if (vector[base][i+1] == '1')
- X shellfile[0] = new_name(vector[base+1]);
- X or (vector[base][i+1] == '2')
- X shellfile[1] = new_name(vector[base+1]);
- X else
- X usage();
- X
- X if (vector[base][i+2] != '\0')
- X usage();
- X
- X cdebug(" -S%c %s", vector[base][i+1], vector[base+1]);
- X (*count)--;
- X vector++, j++;
- X goto nextword;
- X
- X when 'T': putflag(base, vector[base+1]);
- X metachars = new_name(vector[base+1]);
- X if (vector[base][i+1] != '\0')
- X usage();
- X
- X cdebug(" -T %s", metachars);
- X (*count)--;
- X vector++, j++;
- X goto nextword;
- X
- X when 'f': putflag(base, vector[base+1]);
- X cakefile = new_name(vector[base+1]);
- X if (vector[base][i+1] != '\0')
- X usage();
- X
- X cdebug(" -f %s", cakefile);
- X (*count)--;
- X vector++, j++;
- X goto nextword;
- X
- X otherwise: usage();
- X }
- X }
- X
- Xnextword:
- X (*count)--;
- X vector++, j++;
- X }
- X
- X cdebug(" \n%return %d\n", j);
- X return j;
- X}
- X
- X/*
- X** Put a flag into the CAKEFLAGS definition.
- X*/
- X
- Xputflag(base, flag)
- Xreg int base;
- Xreg char *flag;
- X{
- X if (base == 1)
- X {
- X strcat(cakeflagbuf, " ");
- X strcat(cakeflagbuf, flag);
- X if (strlen(cakeflagbuf) >= MAXSIZE)
- X {
- X fprintf(stderr, "cake: CAKEFLAGS too long\n");
- X exit(1);
- X }
- X }
- X}
- X
- X/*
- X** Tell the unfortunate user how to use cake.
- X*/
- X
- Xusage()
- X{
- X fprintf(stderr, "Usage: cake [-abcdgiknqrstvwxzGLRXZ] [-ffile]\n");
- X fprintf(stderr, " [-Ddefn] [-Idir] [-Uname] [-S shell] [-T metachars] [file ...]\n");
- X exit(1);
- X}
- X
- Xexit_cake(needtrail)
- Xreg int needtrail;
- X{
- X if (cakedebug && needtrail)
- X get_trail(stdout);
- X else
- X dir_finish();
- X
- X exit(1);
- X}
- X
- X/*
- X** Handle bus errors and segmentation violations.
- X*/
- X
- Xcake_abort()
- X{
- X
- X signal(SIGINT, SIG_IGN);
- X signal(SIGQUIT, SIG_IGN);
- X
- X printf("Abort on signal\n");
- X if (cakedebug)
- X get_trail(stdout);
- X
- X signal(SIGQUIT, SIG_DFL);
- X kill(getpid(), SIGQUIT);
- X}
- X
- X/*
- X** Handle user interrupts.
- X*/
- X
- Xcake_finish()
- X{
- X reg List *ptr;
- X reg Proc *proc;
- X
- X signal(SIGINT, SIG_IGN);
- X signal(SIGQUIT, SIG_IGN);
- X
- X printf("*** Interrupt\n");
- X fflush(stdout);
- X for_list (ptr, active_procs)
- X {
- X proc = (Proc *) ldata(ptr);
- X if (proc->pr_node != NULL)
- X cake_error(proc->pr_node);
- X }
- X
- X exit_cake(FALSE);
- X}
- X
- X#ifdef STATS_FILE
- X#ifdef ATT
- X#include <sys/times.h>
- X
- Xtypedef struct tms Tms;
- X#else
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X
- Xtypedef struct rusage Rusage;
- X#endif
- X
- Xstatistics()
- X{
- X extern char *getlogin();
- X extern getpw();
- X extern int out_tried, out_found;
- X extern int stat_tried, stat_found;
- X FILE *sfp;
- X
- X if ((sfp = fopen(STATS_FILE, "a")) != NULL)
- X {
- X#ifdef ATT
- X Tms tbuf;
- X#else
- X Rusage s, c;
- X#endif
- X long su, ss, cu, cs;
- X char *usr;
- X
- X if ((usr = getlogin()) == NULL)
- X {
- X char buf[256];
- X char *usr_end;
- X
- X if (getpw(getuid(), buf) != 0)
- X usr = "NULL";
- X else
- X {
- X usr = buf;
- X if ((usr_end = index(usr, ':')) != NULL)
- X *usr_end = '\0';
- X else
- X usr = "NULL";
- X }
- X
- X usr = new_name(usr);
- X }
- X
- X#ifdef ATT
- X if (times(&tbuf) == -1)
- X {
- X fclose(sfp);
- X return;
- X }
- X
- X su = tbuf.tms_utime*100/TIMERES;
- X ss = tbuf.tms_stime*100/TIMERES;
- X cu = tbuf.tms_cutime*100/TIMERES;
- X cs = tbuf.tms_cstime*100/TIMERES;
- X#else
- X getrusage(RUSAGE_SELF, &s);
- X getrusage(RUSAGE_CHILDREN, &c);
- X
- X su = s.ru_utime.tv_sec*100 + s.ru_utime.tv_usec/10000;
- X ss = s.ru_stime.tv_sec*100 + s.ru_stime.tv_usec/10000;
- X cu = c.ru_utime.tv_sec*100 + c.ru_utime.tv_usec/10000;
- X cs = c.ru_stime.tv_sec*100 + c.ru_stime.tv_usec/10000;
- X#endif
- X fprintf(sfp, "%s %ld %ld %ld %ld ", usr, su, ss, cu, cs);
- X fprintf(sfp, "%d %d %d %d %d\n", sbrk(0),
- X out_tried, out_found, stat_tried, stat_found);
- X
- X fclose(sfp);
- X }
- X}
- X#endif
- SHAR_EOF
- if test 9780 -ne "`wc -c < 'main.c'`"
- then
- echo shar: "error transmitting 'main.c'" '(should have been 9780 characters)'
- fi
- fi
- echo shar: "extracting 'make.c'" '(2967 characters)'
- if test -f 'make.c'
- then
- echo shar: "will not over-write existing file 'make.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'make.c'
- X/*
- X** Module to make Cake data structures.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/make.c,v 1.15 87/10/05 20:15:02 zs Exp $";
- X
- X#include "cake.h"
- X
- XNode *
- Xmake_node(name)
- Xreg char *name;
- X{
- X reg Node *node;
- X
- X node = make(Node);
- X node->n_name = name;
- X
- X if (name == NULL)
- X return node;
- X
- X node->n_kind = n_NOWAY; /* not yet */
- X node->n_flag = 0;
- X node->n_old = makelist0();
- X node->n_when = NULL;
- X node->n_act = NULL;
- X node->n_new = makelist(node);
- X#if 0 /* N must be 1 for the time being */
- X node->n_pid = 0;
- X node->n_file = NULL;
- X#endif
- X node_stat(node);
- X node->n_utime = 0;
- X node->n_stime = node->n_rtime;
- X node->n_badguys = NULL;
- X node->n_msg = NULL;
- X
- X return node;
- X}
- X
- XEntry *
- Xmake_dep(new, old, cond, file, colon)
- Xreg List *new; /* of Pat */
- Xreg List *old; /* of Pat */
- Xreg Test *cond;
- Xreg char *file;
- Xreg char *colon;
- X{
- X reg Entry *entry;
- X
- X entry = make(Entry);
- X entry->e_new = new;
- X entry->e_old = old;
- X entry->e_cond = cond;
- X entry->e_file = file;
- X entry->e_dblc = streq(colon, "::");
- X entry->e_when = makelist0();
- X
- X return entry;
- X}
- X
- XTest *
- Xmake_test_mm(name)
- Xreg Pat *name;
- X{
- X reg Test *test;
- X
- X test = make(Test);
- X test->t_kind = t_MATCH;
- X test->t_pat = name;
- X test->t_list = makelist0();
- X
- X return test;
- X}
- X
- XTest *
- Xmake_test_m(name, varpat, pattern)
- Xreg Pat *name;
- Xreg Pat *varpat;
- Xreg Pat *pattern;
- X{
- X reg Test *test;
- X
- X test = make(Test);
- X test->t_kind = t_MATCH;
- X test->t_pat = name;
- X test->t_list = makelist0();
- X
- X if (varpat == NULL)
- X addtail(test->t_list, make_pat("-vX", FALSE, 0));
- X else
- X addtail(test->t_list, varpat); /* no assignment */
- X
- X addtail(test->t_list, pattern); /* no assignment */
- X return test;
- X}
- X
- XTest *
- Xmake_test_c(cmd)
- Xreg char *cmd;
- X{
- X reg Test *test;
- X
- X test = make(Test);
- X test->t_kind = t_CMD;
- X test->t_cmd = cmd;
- X
- X return test;
- X}
- X
- XTest *
- Xmake_test_s(tkind, pat)
- Xreg T_kind tkind;
- Xreg Pat *pat;
- X{
- X reg Test *test;
- X
- X test = make(Test);
- X test->t_kind = tkind;
- X test->t_pat = pat;
- X
- X return test;
- X}
- X
- XTest *
- Xmake_test_l(pat, list)
- Xreg Pat *pat;
- Xreg List *list; /* of Pat */
- X{
- X reg Test *test;
- X
- X test = make(Test);
- X test->t_kind = t_LIST;
- X test->t_pat = pat;
- X test->t_list = list;
- X
- X return test;
- X}
- X
- XTest *
- Xmake_test_b(tkind, left, right)
- Xreg T_kind tkind;
- Xreg Test *left;
- Xreg Test *right;
- X{
- X reg Test *test;
- X
- X test = make(Test);
- X test->t_kind = tkind;
- X test->t_left = left;
- X test->t_right = right;
- X
- X return test;
- X}
- X
- XTest *
- Xmake_test_u(tkind, left)
- Xreg T_kind tkind;
- Xreg Test *left;
- X{
- X reg Test *test;
- X
- X test = make(Test);
- X test->t_kind = tkind;
- X test->t_left = left;
- X test->t_right = (Test *) NULL;
- X
- X return test;
- X}
- X
- XPat *
- Xmake_pat(text, iscmd, flags)
- Xreg char *text;
- Xreg bool iscmd;
- Xreg int flags;
- X{
- X reg Pat *pat;
- X
- X pat = make(Pat);
- X pat->p_str = text;
- X pat->p_cmd = iscmd;
- X pat->p_flag = flags;
- X
- X checkpatlen(text);
- X return pat;
- X}
- X
- XAct *
- Xmake_act(str, flag)
- Xreg char *str;
- Xreg int flag;
- X{
- X reg Act *act;
- X
- X act = make(Act);
- X act->a_str = str;
- X act->a_flag = flag;
- X
- X return act;
- X}
- SHAR_EOF
- if test 2967 -ne "`wc -c < 'make.c'`"
- then
- echo shar: "error transmitting 'make.c'" '(should have been 2967 characters)'
- fi
- fi
- echo shar: "extracting 'mem.c'" '(822 characters)'
- if test -f 'mem.c'
- then
- echo shar: "will not over-write existing file 'mem.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mem.c'
- X/*
- X** Memory management module.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/mem.c,v 1.15 87/10/05 20:15:10 zs Exp $";
- X
- X#include "cake.h"
- X
- X/*
- X** Allocate space if possible. In the future it may record
- X** all pointers returned, so that old can do some checks.
- X*/
- X
- XCast
- Xnewmem(size)
- Xint size;
- X{
- X reg char *space;
- X
- X if ((space = malloc((unsigned) size)) == NULL)
- X {
- X fprintf(stderr, "cake system error: no more malloc\n");
- X exit_cake(FALSE);
- X }
- X
- X#ifdef EXTRACHECK
- X if (((int) space & 03) != 0)
- X {
- X fprintf(stderr, "cake system error: malloc not aligned\n");
- X exit_cake(FALSE);
- X }
- X#endif
- X
- X return (Cast) space;
- X}
- X
- X/*
- X** Return some storage to the free list. This storage must
- X** have been obtained from new and malloc.
- X*/
- X
- X/*ARGSUSED*/
- Xoldmem(ptr)
- XCast ptr;
- X{
- X#ifdef MEMUSED
- X free((char *) ptr);
- X#endif
- X}
- SHAR_EOF
- if test 822 -ne "`wc -c < 'mem.c'`"
- then
- echo shar: "error transmitting 'mem.c'" '(should have been 822 characters)'
- fi
- fi
- echo shar: "extracting 'pat.c'" '(6360 characters)'
- if test -f 'pat.c'
- then
- echo shar: "will not over-write existing file 'pat.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'pat.c'
- X/*
- X** Module to manipulate Cake patterns.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/pat.c,v 1.15 87/10/05 20:15:15 zs Exp $";
- X
- X#include "cake.h"
- X#include <ctype.h>
- X
- X/*
- X** This function serves as an interface to the rest of the system
- X** for domatch, looking after its environment.
- X*/
- X
- Xbool
- Xmatch(env, str, pat)
- XEnv env;
- Xreg char *str;
- Xreg Pat *pat;
- X{
- X extern bool domatch();
- X reg bool result;
- X reg int i;
- X reg char *s, *p;
- X
- X if (patdebug)
- X printf("Match %s vs %s\n", str, pat->p_str);
- X
- X if (pat->p_cmd)
- X {
- X fprintf(stderr, "cake internal error: undereferenced pattern %s in match\n",
- X pat->p_str);
- X exit_cake(TRUE);
- X }
- X
- X if (streq(str, CHASEROOT))
- X result = streq(pat->p_str, CHASEROOT);
- X else
- X {
- X result = TRUE; /* assume so for the moment */
- X p = pat->p_str+strlen(pat->p_str)-1;
- X if (*p != '%' && !isdigit(*p)) /* not part of a var */
- X {
- X s = str+strlen(str)-1;
- X if (*s != *p) /* last chars differ */
- X result = FALSE;
- X }
- X
- X if (result) /* if last-char test inconclusive */
- X {
- X for (i = 0; i < MAXVAR; i++)
- X env[i].v_bound = FALSE;
- X
- X result = domatch(env, str, pat->p_str);
- X }
- X }
- X
- X if (patdebug)
- X {
- X if (result == FALSE)
- X printf("Match failed\n");
- X else
- X {
- X printf("Match succeeded\n");
- X for (i = 0; i < MAXVAR; i++)
- X if (env[i].v_bound)
- X printf("X%d: %s\n", i, env[i].v_val);
- X }
- X }
- X
- X return result;
- X}
- X
- X/*
- X** Match a string against a pattern.
- X** The pattern is expected to have been dereferenced.
- X** To handle nondeterminism, a brute force recursion approach
- X** is taken.
- X*/
- X
- Xbool
- Xdomatch(env, str, patstr)
- XEnv env;
- Xreg char *str;
- Xreg char *patstr;
- X{
- X char buf[MAXPATSIZE];
- X reg char *follow;
- X reg char *s, *t;
- X reg int varno;
- X reg int i;
- X reg bool more;
- X
- X put_trail("domatch", "start");
- X if (patstr[0] == '%')
- X {
- X if (isdigit(patstr[1]))
- X {
- X varno = patstr[1] - '0';
- X follow = patstr + 2;
- X }
- X else
- X {
- X varno = NOVAR;
- X follow = patstr + 1;
- X }
- X
- X if (env[varno].v_bound)
- X {
- X /* lifetime of buf is local */
- X strcpy(buf, env[varno].v_val);
- X strcat(buf, follow);
- X checkpatlen(buf);
- X put_trail("domatch", "recurse");
- X return domatch(env, str, buf);
- X }
- X
- X i = 0;
- X buf[0] = '\0';
- X env[varno].v_bound = TRUE;
- X env[varno].v_val = buf;
- X
- X /* keep invariant: buf = tentative value of var */
- X /* the value of a variable may never contain a % */
- X /* must consider *s == \0, but do not overshoot */
- X for (s = str, more = TRUE; more && *s != '%'; s++)
- X {
- X if (patdebug)
- X printf("trying X%d = '%s'\n", varno, buf);
- X
- X if (domatch(env, s, follow))
- X {
- X checkpatlen(buf);
- X env[varno].v_val = new_name(buf);
- X /* lifetime of buf is now global */
- X put_trail("domatch", "finish");
- X return TRUE;
- X }
- X
- X /* maintain invariant */
- X buf[i++] = *s;
- X buf[i] = '\0';
- X
- X more = (*s != '\0');
- X }
- X
- X /* no luck, match failed */
- X env[varno].v_bound = FALSE;
- X put_trail("domatch", "finish");
- X return FALSE;
- X }
- X
- X /* here we have something other than a variable first off */
- X for (s = str, t = patstr; *t != '\0' && *t != '%'; s++, t++)
- X {
- X if (*t == '\\')
- X t++; /* the new *t is not checked for % */
- X
- X if (*s != *t)
- X {
- X put_trail("domatch", "finish");
- X return FALSE;
- X }
- X }
- X
- X /* see if we have come to the end of the pattern */
- X if (*t == '\0')
- X {
- X put_trail("domatch", "finish");
- X return *s == '\0';
- X }
- X
- X /* if not, recurse on the next variable */
- X put_trail("domatch", "recurse");
- X return domatch(env, s, t);
- X}
- X
- X/*
- X** Ground the argument string, i.e. replace all occurrences
- X** of variables in it. It is fatal error for the string to
- X** contain a variable which has no value.
- X*/
- X
- Xchar *
- Xground(env, str)
- XEnv env;
- Xreg char *str;
- X{
- X reg char *s, *t;
- X reg int i, var;
- X char buf[MAXSIZE];
- X
- X put_trail("ground", "start");
- X i = 0;
- X for (s = str; *s != '\0'; s++)
- X {
- X if (*s == '%')
- X {
- X if (isdigit(s[1]))
- X var = *++s - '0';
- X else
- X var = NOVAR;
- X
- X if (! env[var].v_bound)
- X {
- X if (var == NOVAR)
- X fprintf(stderr, "cake: %s is undefined in %s\n", "%", str);
- X else
- X fprintf(stderr, "cake: %s%1d is undefined in %s\n", "%", var, str);
- X exit_cake(FALSE);
- X }
- X
- X for (t = env[var].v_val; *t != '\0'; t++)
- X buf[i++] = *t;
- X }
- X or (*s == '\\')
- X {
- X if (s[1] != '\0')
- X buf[i++] = *++s;
- X }
- X else
- X buf[i++] = *s;
- X }
- X
- X buf[i] = '\0';
- X if (i >= MAXSIZE)
- X {
- X fprintf(stderr, "cake internal error: pattern buffer overflow for %s\n", buf);
- X exit_cake(FALSE);
- X }
- X
- X put_trail("ground", "new_name finish");
- X return new_name(buf);
- X}
- X
- X/*
- X** See if the argument contains any variebles.
- X*/
- X
- Xbool
- Xhasvars(str)
- Xreg char *str;
- X{
- X reg char *s;
- X
- X for (s = str; *s != '\0'; s++)
- X {
- X if (*s == '%')
- X return TRUE;
- X or (*s == '\\')
- X {
- X if (s[1] != '\0')
- X s++;
- X }
- X }
- X
- X return FALSE;
- X}
- X
- X/*
- X** Dereference the pattern; i.e. if it a command pattern
- X** replace it with the output of the command. It is the task
- X** of the caller to break this up if necessary.
- X** Note that the pattern will never have to be dereferenced again.
- X**
- X** The second arg says whether the pattern is to be broken after
- X** dereferencing: this is needed purely for debugging purposes.
- X*/
- X
- Xderef(pat, broken)
- Xreg Pat *pat;
- Xreg bool broken;
- X{
- X extern char *expand_cmds();
- X
- X if (! pat->p_cmd)
- X return;
- X
- X pat->p_cmd = FALSE;
- X pat->p_str = expand_cmds(pat->p_str);
- X
- X if (! broken)
- X checkpatlen(pat->p_str);
- X}
- X
- X/*
- X** Break the given pattern up into a (possibly empty) list
- X** of smaller patterns at white space positions.
- X*/
- X
- XList *
- Xbreak_pat(pat)
- Xreg Pat *pat;
- X{
- X reg Pat *newpat;
- X reg List *list;
- X reg char *s;
- X
- X put_trail("break_pat", "start");
- X if (pat->p_cmd)
- X {
- X fprintf(stderr, "cake internal error: trying to break command pattern %s\n", pat->p_str);
- X exit_cake(TRUE);
- X }
- X
- X list = makelist0();
- X s = pat->p_str;
- X while (*s != '\0')
- X {
- X char buf[MAXSIZE];
- X reg int i;
- X
- X for (; *s != '\0' && isspace(*s); s++)
- X ;
- X
- X i = 0;
- X for (; *s != '\0' && !isspace(*s); s++)
- X buf[i++] = *s;
- X
- X buf[i] = '\0';
- X if (i > 0)
- X {
- X newpat = make_pat(new_name(buf), FALSE, pat->p_flag);
- X addtail(list, newpat); /* no assignment */
- X }
- X }
- X
- X put_trail("break_pat", "finish");
- X return list;
- X}
- X
- X/*
- X** Add flags to a list of patterns.
- X*/
- X
- XList *
- Xset_flag(patlist, flags)
- Xreg List *patlist;
- Xreg int flags;
- X{
- X reg List *ptr;
- X reg Pat *pat;
- X
- X for_list (ptr, patlist)
- X {
- X pat = (Pat *) ldata(ptr);
- X pat->p_flag |= flags;
- X }
- X
- X return patlist;
- X}
- SHAR_EOF
- if test 6360 -ne "`wc -c < 'pat.c'`"
- then
- echo shar: "error transmitting 'pat.c'" '(should have been 6360 characters)'
- fi
- fi
- echo shar: "extracting 'print.c'" '(4954 characters)'
- if test -f 'print.c'
- then
- echo shar: "will not over-write existing file 'print.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'print.c'
- X/*
- X** Printout routines for Cake data structures.
- X*/
- X
- X#ifdef CAKEDEBUG
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/print.c,v 1.15 87/10/05 20:15:33 zs Exp $";
- X
- X#include "cake.h"
- X
- Xchar *
- Xstr_pflag(flag)
- Xreg int flag;
- X{
- X char buf[256];
- X
- X strcpy(buf, "[");
- X if (flag & nf_NONVOL)
- X strcat(buf, "nonvol ");
- X if (flag & nf_PRECIOUS)
- X strcat(buf, "precious ");
- X if (flag & nf_PSEUDO)
- X strcat(buf, "pseudo ");
- X if (flag & nf_REDUNDANT)
- X strcat(buf, "redundant ");
- X if (flag & nf_WHEN)
- X strcat(buf, "when ");
- X if (flag & nf_DEPNONVOL)
- X strcat(buf, "depnonvol ");
- X if (flag & nf_NODELETE)
- X strcat(buf, "nodelete ");
- X if (flag & nf_NEWFILE)
- X strcat(buf, "newfile ");
- X if (flag & nf_EXIST)
- X strcat(buf, "exist ");
- X if (flag & nf_BUSY)
- X strcat(buf, "busy ");
- X if (flag & nf_ERR)
- X strcat(buf, "err ");
- X if (flag & nf_TRACED)
- X strcat(buf, "traced ");
- X if (flag & nf_WARNED)
- X strcat(buf, "warned ");
- X if (flag & nf_ORIG)
- X strcat(buf, "orig ");
- X
- X if (strlen(buf) > 1)
- X buf[strlen(buf)-1] = '\0';
- X
- X strcat(buf, "]");
- X return new_name(buf);
- X}
- X
- Xchar *
- Xstr_aflag(flag)
- Xreg int flag;
- X{
- X char buf[128];
- X
- X strcpy(buf, "[");
- X if (flag & af_SILENT)
- X strcat(buf, "silent ");
- X if (flag & af_IGNORE)
- X strcat(buf, "ignore ");
- X if (flag & af_MINUSN)
- X strcat(buf, "minusn ");
- X if (flag & af_SYSTEM)
- X strcat(buf, "system ");
- X if (flag & af_SCRIPT)
- X strcat(buf, "script ");
- X
- X if (strlen(buf) > 1)
- X buf[strlen(buf)-1] = '\0';
- X
- X strcat(buf, "]");
- X return new_name(buf);
- X}
- X
- Xprint_pat(pat)
- Xreg Pat *pat;
- X{
- X if (pat->p_cmd)
- X printf("`%s`", pat->p_str);
- X else
- X printf("%s", pat->p_str);
- X
- X printf(str_pflag(pat->p_flag));
- X}
- X
- Xprint_act(act)
- Xreg Act *act;
- X{
- X printf(str_aflag(act->a_flag));
- X printf("%s", act->a_str);
- X}
- X
- Xprint_test(test)
- Xreg Test *test;
- X{
- X reg List *ptr;
- X reg char *pre;
- X reg Pat *pat;
- X
- X if (test == NULL)
- X {
- X printf("null");
- X return;
- X }
- X
- X switch (test->t_kind)
- X {
- X
- Xwhen t_TRUE: printf("true");
- Xwhen t_FALSE: printf("false");
- X
- Xwhen t_AND: print_test(test->t_left);
- X printf(" and ");
- X print_test(test->t_right);
- X
- Xwhen t_OR: print_test(test->t_left);
- X printf(" or ");
- X print_test(test->t_right);
- X
- Xwhen t_NOT: printf("not ");
- X print_test(test->t_left);
- X
- Xwhen t_CMD: printf("cmd `%s`", test->t_cmd);
- X
- Xwhen t_MATCH: printf("match ");
- X print_pat(test->t_pat);
- X printf(" against");
- X printf(" (");
- X print_pat((Pat *) first(test->t_list));
- X printf(") ");
- X print_pat((Pat *) last(test->t_list));
- X
- Xwhen t_LIST: printf("list ");
- X print_pat(test->t_pat);
- X
- X printf(" in (");
- X pre = "";
- X for_list (ptr, test->t_list)
- X {
- X pat = (Pat *) ldata(ptr);
- X printf(pre);
- X print_pat(pat);
- X pre = ", ";
- X }
- X
- X printf(")");
- X
- Xwhen t_EXIST: printf("exist ");
- X print_pat(test->t_pat);
- X
- Xwhen t_CANDO: printf("cando ");
- X print_pat(test->t_pat);
- X
- Xwhen t_OK: printf("ok ");
- X print_pat(test->t_pat);
- X
- Xotherwise: printf("Bad type kind %d in print_test\n", test->t_kind);
- X
- X }
- X}
- X
- Xprint_entry(entry)
- Xreg Entry *entry;
- X{
- X reg List *ptr;
- X reg Pat *pat;
- X reg Act *act;
- X reg char *pre;
- X
- X printf("ENTRY\nnew: ");
- X pre = "";
- X for_list (ptr, entry->e_new)
- X {
- X pat = (Pat *) ldata(ptr);
- X printf(pre);
- X print_pat(pat);
- X pre = ", ";
- X }
- X
- X printf("\nold: ");
- X pre = "";
- X for_list (ptr, entry->e_old)
- X {
- X pat = (Pat *) ldata(ptr);
- X printf(pre);
- X print_pat(pat);
- X pre = ", ";
- X }
- X
- X printf("\nwhen: ");
- X pre = "";
- X for_list (ptr, entry->e_when)
- X {
- X pat = (Pat *) ldata(ptr);
- X printf(pre);
- X print_pat(pat);
- X pre = ", ";
- X }
- X
- X printf("\ntest: ");
- X print_test(entry->e_cond);
- X
- X printf("\nactions:\n");
- X for_list (ptr, entry->e_act)
- X {
- X act = (Act *) ldata(ptr);
- X print_act(act);
- X }
- X
- X printf("\n");
- X}
- X
- Xchar *
- Xstr_nkind(nkind)
- Xreg N_kind nkind;
- X{
- X switch (nkind)
- X {
- Xwhen n_OK: return "ok";
- Xwhen n_NOWAY: return "noway";
- Xwhen n_CANDO: return "cando";
- X }
- X
- X return "bizarre";
- X}
- X
- Xprint_time(str, ntime)
- Xreg char *str;
- Xtime_t ntime;
- X{
- X extern char *ctime();
- X
- X printf("%s time: %d, %s", str, ntime, ctime(&ntime));
- X}
- X
- Xprint_node(node)
- Xreg Node *node;
- X{
- X reg List *ptr;
- X reg char *pre;
- X reg Node *bnode;
- X reg Act *act;
- X
- X printf("\nNODE\n%s: kind %s flag %s\n", node->n_name,
- X str_nkind(node->n_kind), str_pflag(node->n_flag));
- X print_time("real", node->n_rtime);
- X print_time("used", node->n_utime);
- X print_time("saved", node->n_stime);
- X
- X printf("new: ");
- X pre = "";
- X for_list (ptr, node->n_new)
- X {
- X bnode = (Node *) ldata(ptr);
- X printf(pre);
- X printf(bnode->n_name);
- X pre = ", ";
- X }
- X
- X printf("\nold: ");
- X pre = "";
- X for_list (ptr, node->n_old)
- X {
- X bnode = (Node *) ldata(ptr);
- X printf(pre);
- X printf(bnode->n_name);
- X pre = ", ";
- X }
- X
- X printf("\naction:\n");
- X for_list (ptr, node->n_act)
- X {
- X act = (Act *) ldata(ptr);
- X print_act(act);
- X }
- X
- X if (node->n_badguys != (List *) NULL)
- X {
- X printf("bad guys: ");
- X pre = "";
- X for_list (ptr, node->n_badguys)
- X {
- X bnode = (Node *) ldata(ptr);
- X printf(pre);
- X printf(bnode->n_name);
- X pre = ", ";
- X }
- X
- X printf("\n");
- X }
- X
- X if (node->n_msg != NULL)
- X printf("msg: %s", node->n_msg);
- X
- X printf("\n");
- X}
- X
- X#endif
- SHAR_EOF
- if test 4954 -ne "`wc -c < 'print.c'`"
- then
- echo shar: "error transmitting 'print.c'" '(should have been 4954 characters)'
- fi
- fi
- echo shar: "extracting 'proc.c'" '(8939 characters)'
- if test -f 'proc.c'
- then
- echo shar: "will not over-write existing file 'proc.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'proc.c'
- X/*
- X** Cake interface to the other processes.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/proc.c,v 1.15 87/10/05 20:15:45 zs Exp $";
- X
- X#include "cake.h"
- X#include <ctype.h>
- X#include <errno.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#include <sys/param.h>
- X
- Xextern List *active_procs; /* of Proc */
- X
- X/*
- X** Process the given command in the manner described by the args.
- X*/
- X
- Xint
- Xcake_proc(cmd, type, file, node, func, args)
- Xreg char *cmd;
- Xreg A_kind type;
- Xreg char *file;
- Xreg Node *node;
- Xreg int (*func)();
- Xreg List *args;
- X{
- X extern bool has_meta();
- X extern char *strip_backslash();
- X extern char *shell_path[2];
- X extern char *shell_cmd[2];
- X extern char *shell_opt[2];
- X char *argv[MAXARGS];
- X reg Proc *proc;
- X reg int pid;
- X reg char *script_filename;
- X
- X cmd = strip_backslash(cmd);
- X
- X#ifdef CAKEDEBUG
- X if (file != NULL)
- X cdebug("file is %s\n", file);
- X else
- X cdebug("file is NULL\n");
- X#endif
- X
- X if (type == Exec && has_meta(cmd, TRUE))
- X type = System;
- X
- X cdebug("cake_proc, type %d: %s\n", type, cmd);
- X fflush(stdout);
- X
- X if (type == Exec)
- X parse_args(cmd, argv);
- X or (type == Script)
- X {
- X reg FILE *script_fp;
- X
- X script_filename = get_newname();
- X if ((script_fp = fopen(script_filename, "w")) == NULL)
- X {
- X sprintf(scratchbuf, "cake system error, fopen %s", script_filename);
- X perror(scratchbuf);
- X exit_cake(FALSE);
- X }
- X
- X fprintf(script_fp, "%s", cmd);
- X fclose(script_fp);
- X }
- X
- X mutex_lock();
- X if ((pid = vfork()) == 0)
- X {
- X reg int fd;
- X
- X#ifdef CLOSE_ALL
- X for (fd = 3; fd < NOFILE; fd++)
- X close(fd);
- X#endif
- X
- X if (file != NULL)
- X {
- X if (close(1) != 0)
- X {
- X perror("cake system error, close stdout");
- X _exit(127);
- X }
- X
- X if ((fd = open(file, O_WRONLY|O_CREAT, 0600)) < 0)
- X {
- X perror("cake system error, reopen stdout");
- X _exit(127);
- X }
- X
- X if (fd != 1)
- X {
- X fprintf(stderr, "cake system error: reopen stdout gives fd %d\n", fd);
- X _exit(127);
- X }
- X }
- X
- X switch (type)
- X {
- X
- X when Script: if (shell_opt[1] != NULL)
- X execl(shell_path[1], shell_cmd[1], shell_opt[1], script_filename, 0);
- X else
- X execl(shell_path[1], shell_cmd[1], script_filename, 0);
- X
- X perror("cake system error, shell script exec");
- X _exit(127);
- X
- X when System: if (shell_opt[0] != NULL)
- X execl(shell_path[0], shell_cmd[0], shell_opt[0], cmd, 0);
- X else
- X execl(shell_path[0], shell_cmd[0], cmd, 0);
- X
- X perror("cake system error, shell exec");
- X _exit(127);
- X
- X when Exec: execvp(argv[0], argv);
- X sprintf(scratchbuf, "cake system error, %s exec", argv[0]);
- X perror(scratchbuf);
- X _exit(127);
- X
- X otherwise: fprintf(stderr, "cake internal error: type = %x in cake_proc\n", type);
- X _exit(127);
- X }
- X }
- X or (pid == -1)
- X {
- X perror("cake system error, fork");
- X exit_cake(FALSE);
- X }
- X
- X proc = make(Proc);
- X proc->pr_pid = pid;
- X proc->pr_node = node;
- X proc->pr_func = func;
- X proc->pr_args = args;
- X proc->pr_run = TRUE;
- X addtail(active_procs, proc);
- X cdebug("cake_proc pid = %d\n", pid);
- X
- X mutex_unlock();
- X if (type == Script && ! cakedebug)
- X {
- X cdebug("cake_proc unlink script_filename %s\n", script_filename);
- X if (unlink(script_filename) != 0)
- X {
- X sprintf(scratchbuf, "cake system error, unlink %s", script_filename);
- X perror(scratchbuf);
- X exit_cake(FALSE);
- X }
- X }
- X
- X return pid;
- X}
- X
- X/*
- X** The cake code allows many child processes to be running
- X** at any given time. Cake waits for these processes
- X** when their results are required. However, there is no
- X** necessary relationship between between when a process exits
- X** and when its product is needed.
- X**
- X** The list of active processes contains all running processes
- X** and all exited processes that haven't been waited for yet.
- X** Cake_wait maintains this list. Whenever cake_wait gets
- X** an exit report from wait, it invokes the function (if any)
- X** associated with the exited process. If the exited process
- X** is the one cake_wait is looking for, it returns; otherwise
- X** it calls wait again and again until it finds that process.
- X*/
- X
- XWait
- Xcake_wait(pid)
- Xreg int pid;
- X{
- X extern List *find_process();
- X reg int exitpid;
- X reg List *ptr;
- X reg Proc *proc;
- X Wait status;
- X
- X mutex_lock();
- X ptr = find_process(pid);
- X proc = (Proc *) ldata(ptr);
- X if (! proc->pr_run)
- X {
- X status = proc->pr_stat;
- X delete(active_procs, ptr);
- X mutex_unlock();
- X return status;
- X }
- X
- X while ((exitpid = wait(&status)) != -1)
- X {
- X mutex_lock();
- X ptr = find_process(exitpid);
- X proc = (Proc *) ldata(ptr);
- X proc->pr_run = FALSE;
- X proc->pr_stat = status;
- X cdebug("cake_wait pid = %d, status = %d\n", exitpid, status.w_status);
- X fflush(stdout);
- X
- X if (proc->pr_func != NULL)
- X {
- X cdebug("cake_wait calling function at %x\n", proc->pr_func);
- X fflush(stdout);
- X (*proc->pr_func)(status, proc->pr_args);
- X }
- X
- X if (exitpid == pid)
- X {
- X delete(active_procs, ptr);
- X mutex_unlock();
- X return status; /* normal return */
- X }
- X
- X mutex_unlock();
- X }
- X
- X fprintf(stderr, "cake internal error: waiting for nonactive process %s\n", pid);
- X exit_cake(TRUE);
- X return status; /* to shut up lint */
- X}
- X
- X/*
- X** Find an active process in the active process list.
- X*/
- X
- XList *
- Xfind_process(pid)
- Xreg int pid;
- X{
- X reg List *ptr;
- X reg Proc *proc;
- X reg bool found;
- X
- X found = FALSE;
- X for_list (ptr, active_procs)
- X {
- X proc = (Proc *) ldata(ptr);
- X if (proc->pr_pid == pid)
- X {
- X found = TRUE;
- X break;
- X }
- X }
- X
- X if (! found)
- X {
- X fprintf(stderr, "cake internal error: cannot find active process %d\n", pid);
- X exit_cake(TRUE);
- X }
- X
- X return ptr;
- X}
- X
- X/*
- X** Open a filter the cake way, with an execv instead of an execl.
- X*/
- X
- X#define READSIDE 0
- X#define WRITESIDE 1
- X
- Xstatic int popen_pid[NOFILE];
- X
- XFILE *
- Xcake_popen(argv, mode)
- Xreg char *argv[MAXARGS];
- Xreg char *mode;
- X{
- X int pdesc[2];
- X reg int parent_end, child_end;
- X reg int replaced, pid;
- X reg Proc *proc;
- X
- X if (pipe(pdesc) < 0)
- X return NULL;
- X
- X if (mode[0] == 'r')
- X {
- X parent_end = pdesc[READSIDE];
- X child_end = pdesc[WRITESIDE];
- X replaced = 1;
- X }
- X else
- X {
- X parent_end = pdesc[WRITESIDE];
- X child_end = pdesc[READSIDE];
- X replaced = 0;
- X }
- X
- X fflush(stdout);
- X mutex_lock();
- X if ((pid = vfork()) == 0)
- X {
- X close(parent_end);
- X close(replaced);
- X if (dup(child_end) != replaced)
- X _exit(127);
- X
- X close(child_end);
- X execv(argv[0], argv);
- X sprintf(scratchbuf, "cake system error, %s exec", argv[0]);
- X perror(scratchbuf);
- X _exit(127);
- X }
- X or (pid == -1)
- X {
- X close(parent_end);
- X close(child_end);
- X perror("cake system error, fork");
- X exit_cake(FALSE);
- X }
- X
- X proc = make(Proc);
- X proc->pr_pid = pid;
- X proc->pr_func = NULL;
- X proc->pr_args = NULL;
- X proc->pr_run = TRUE;
- X addtail(active_procs, proc);
- X
- X close(child_end);
- X popen_pid[parent_end] = pid;
- X mutex_unlock();
- X
- X return fdopen(parent_end, mode);
- X}
- X
- Xint
- Xcake_pclose(fp)
- Xreg FILE *fp;
- X{
- X Wait code;
- X reg int f;
- X
- X f = fileno(fp);
- X fclose(fp);
- X code = cake_wait(popen_pid[f]);
- X return code.w_status;
- X}
- X
- X/*
- X** Parse the given command into argv, argc.
- X*/
- X
- Xint
- Xparse_args(cmd, vector)
- Xreg char *cmd;
- Xreg char **vector;
- X{
- X char buf[MAXARGSIZE];
- X reg int i, count;
- X reg char *s;
- X reg bool instring;
- X
- X cdebug("parse_args: ");
- X
- X s = cmd;
- X for (count = 0; *s != '\0'; count++)
- X {
- X while (*s != '\0' && isspace(*s))
- X s++;
- X
- X instring = FALSE;
- X for (i = 0; *s != '\0' && (! isspace(*s) || instring); s++)
- X {
- X if (*s == '\\')
- X {
- X if (s[1] != '\0')
- X buf[i++] = *++s;
- X }
- X or (*s == '"')
- X instring = ! instring;
- X else
- X buf[i++] = *s;
- X }
- X
- X buf[i] = '\0';
- X if (i >= MAXARGSIZE)
- X {
- X fprintf(stderr, "cake: argument '%s' too long\n", buf);
- X exit_cake(FALSE);
- X }
- X
- X if (count >= MAXARGS)
- X {
- X fprintf(stderr, "cake: '%s' has too many arguments\n", cmd);
- X exit_cake(FALSE);
- X }
- X
- X if (i == 0)
- X count--;
- X else
- X {
- X cdebug("<%s>", buf);
- X vector[count] = new_name(buf);
- X }
- X }
- X
- X vector[count] = NULL;
- X cdebug("/%d\n", count);
- X return count;
- X}
- X
- X/*
- X** Strip one level of backslashes from the given string.
- X*/
- X
- Xchar *
- Xstrip_backslash(str)
- Xreg char *str;
- X{
- X char buf[MAXSIZE];
- X reg char *s;
- X reg int i;
- X
- X if (index(str, '\\') == NULL)
- X return str;
- X
- X for (i = 0, s = str; *s != '\0'; s++)
- X {
- X if (*s != '\\')
- X buf[i++] = *s;
- X or (s[1] != '\0')
- X buf[i++] = *++s;
- X }
- X
- X buf[i] = '\0';
- X if (i >= MAXSIZE)
- X {
- X fprintf(stderr, "cake: command '%s' too long.\n", str);
- X exit_cake(FALSE);
- X }
- X
- X return new_name(buf);
- X}
- X
- X/*
- X** These functions implement mutual exclusion.
- X** They prevent cake from being interrupted
- X** between calls to lock and unlock.
- X** This is used to preserve the consistency
- X** of the active_procs data structure in the presence
- X** of multiple executing children.
- X*/
- X
- X#if 0 /* mutual exclusion is not necessary & has bug */
- X#ifdef ATT
- Xint (*signalint)();
- Xint (*signalquit)();
- X#else
- Xint signalmask;
- X#endif
- X#endif
- X
- Xmutex_lock()
- X{
- X#if 0
- X#ifdef ATT
- X signalint = signal(SIGINT, SIG_IGN);
- X signalquit = signal(SIGQUIT, SIG_IGN);
- X#else
- X signalmask = sigblock(mask(SIGINT)|mask(SIGQUIT));
- X#endif
- X#endif
- X}
- X
- Xmutex_unlock()
- X{
- X#if 0
- X#ifdef ATT
- X signal(SIGINT, signalint);
- X signal(SIGQUIT, signalquit);
- X#else
- X sigsetmask(signalmask);
- X#endif
- X#endif
- X}
- SHAR_EOF
- if test 8939 -ne "`wc -c < 'proc.c'`"
- then
- echo shar: "error transmitting 'proc.c'" '(should have been 8939 characters)'
- fi
- fi
- echo shar: "extracting 'sym.c'" '(4553 characters)'
- if test -f 'sym.c'
- then
- echo shar: "will not over-write existing file 'sym.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'sym.c'
- X/*
- X** Symbol table module
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/sym.c,v 1.15 87/10/05 20:16:08 zs Exp $";
- X
- X#include "cake.h"
- X
- Xtypedef struct s_out
- X{
- X char *o_cmd;
- X char *o_out;
- X} Out;
- X
- Xtypedef struct s_stat
- X{
- X char *s_cmd;
- X int s_stat;
- X} Stat;
- X
- Xextern int hash();
- Xextern Cast name_key(); extern bool name_equal();
- Xextern Cast node_key(); extern bool node_equal();
- Xextern Cast out_key(); extern bool out_equal();
- Xextern Cast stat_key(); extern bool stat_equal();
- XTable name_tab = { SIZE, NULL, name_key, hash, name_equal };
- XTable node_tab = { SIZE, NULL, node_key, hash, node_equal };
- XTable out_tab = { SIZE, NULL, out_key, hash, out_equal };
- XTable stat_tab = { SIZE, NULL, stat_key, hash, stat_equal };
- X
- X/*
- X** Initialize the name and the command tables.
- X*/
- X
- Xinit_sym()
- X{
- X init_table(name_tab);
- X init_table(node_tab);
- X init_table(out_tab);
- X init_table(stat_tab);
- X}
- X
- X/**********************************************************************/
- X/* Name table */
- X
- X/*
- X** Save the given string in the name table if not already there;
- X** return its new address. This address is unique, so comparing
- X** two identifiers for equality can be done by comparing their
- X** addresses.
- X*/
- X
- Xchar *
- Xnew_name(str)
- Xreg char *str;
- X{
- X reg Cast old;
- X reg char *copy;
- X
- X if ((old = lookup_table(name_tab, str)) != NULL)
- X return (char *) old;
- X
- X copy = (char *) newmem(strlen(str) + 1);
- X strcpy(copy, str);
- X insert_table(name_tab, copy);
- X
- X return copy;
- X}
- X
- XCast
- Xname_key(entry)
- Xreg Cast entry;
- X{
- X return entry;
- X}
- X
- Xbool
- Xname_equal(key1, key2)
- Xreg Cast key1, key2;
- X{
- X return streq((char *) key1, (char *) key2);
- X}
- X
- X/**********************************************************************/
- X/* Node table */
- X
- X/*
- X** Th insertion function for the node table is chase(),
- X** which is in chase.c with the rest of the chase stuff.
- X*/
- X
- X/*
- X** This function merely reports on the results
- X** of past calls to chase.
- X*/
- X
- XNode *
- Xchase_node(name)
- Xreg char *name;
- X{
- X return (Node *) lookup_table(node_tab, name);
- X}
- X
- X/*
- X** Return a list of all the nodes of this run.
- X*/
- X
- XList *
- Xget_allnodes()
- X{
- X return contents_table(node_tab);
- X}
- X
- XCast
- Xnode_key(entry)
- Xreg Cast entry;
- X{
- X return (Cast) ((Node *) entry)->n_name;
- X}
- X
- Xbool
- Xnode_equal(key1, key2)
- Xreg Cast key1, key2;
- X{
- X#ifdef EXTRACHECK
- X if (key1 != key2 && streq((char *) key1, (char *) key2))
- X {
- X fprintf(stderr, "cake internal error: inconsistency in node_equal\n");
- X exit_cake(TRUE);
- X }
- X#endif
- X
- X return key1 == key2;
- X}
- X
- X/**********************************************************************/
- X/* Command output table */
- X
- X#ifdef STATS_FILE
- Xint out_tried = 0;
- Xint out_found = 0;
- X#endif
- X
- X/*
- X** Save a command and its output.
- X*/
- X
- Xnew_out(cmd, output)
- Xreg char *cmd;
- Xreg char *output;
- X{
- X reg Out *out;
- X
- X out = make(Out);
- X out->o_cmd = cmd;
- X out->o_out = output;
- X insert_table(out_tab, out);
- X}
- X
- X/*
- X** Return the output if any associated with a given command.
- X*/
- X
- Xchar *
- Xget_out(cmd)
- Xreg char *cmd;
- X{
- X reg Out *out;
- X
- X#ifdef STATS_FILE
- X out_tried++;
- X#endif
- X
- X if ((out = (Out *) lookup_table(out_tab, cmd)) == NULL)
- X return NULL;
- X
- X#ifdef STATS_FILE
- X out_found++;
- X#endif
- X
- X return out->o_out;
- X}
- X
- XCast
- Xout_key(entry)
- Xreg Cast entry;
- X{
- X return (Cast) ((Out *) entry)->o_cmd;
- X}
- X
- Xbool
- Xout_equal(key1, key2)
- Xreg Cast key1, key2;
- X{
- X#ifdef EXTRACHECK
- X if (key1 != key2 && streq((char *) key1, (char *) key2))
- X {
- X fprintf(stderr, "cake internal error: inconsistency in out_equal\n");
- X exit_cake(TRUE);
- X }
- X#endif
- X
- X return key1 == key2;
- X}
- X
- X/**********************************************************************/
- X/* Command status table */
- X
- X#ifdef STATS_FILE
- Xint stat_tried = 0;
- Xint stat_found = 0;
- X#endif
- X
- X/*
- X** Save a command and its status.
- X*/
- X
- Xnew_stat(cmd, status)
- Xreg char *cmd;
- Xreg int status;
- X{
- X reg Stat *stat;
- X
- X stat = make(Stat);
- X stat->s_cmd = cmd;
- X stat->s_stat = status;
- X insert_table(stat_tab, stat);
- X}
- X
- X/*
- X** Return the status if any associated with a given command.
- X*/
- X
- Xbool
- Xget_stat(cmd, code)
- Xreg char *cmd;
- Xreg int *code;
- X{
- X reg Stat *stat;
- X
- X#ifdef STATS_FILE
- X stat_tried++;
- X#endif
- X
- X if ((stat = (Stat *) lookup_table(stat_tab, cmd)) == NULL)
- X return FALSE;
- X
- X#ifdef STATS_FILE
- X stat_found++;
- X#endif
- X
- X *code = stat->s_stat;
- X return TRUE;
- X}
- X
- XCast
- Xstat_key(entry)
- Xreg Cast entry;
- X{
- X return (Cast) ((Stat *) entry)->s_cmd;
- X}
- X
- Xbool
- Xstat_equal(key1, key2)
- Xreg Cast key1, key2;
- X{
- X#ifdef EXTRACHECK
- X if (key1 != key2 && streq((char *) key1, (char *) key2))
- X {
- X fprintf(stderr, "cake internal error: inconsistency in stat_equal\n");
- X exit_cake(TRUE);
- X }
- X#endif
- X
- X return key1 == key2;
- X}
- SHAR_EOF
- if test 4553 -ne "`wc -c < 'sym.c'`"
- then
- echo shar: "error transmitting 'sym.c'" '(should have been 4553 characters)'
- fi
- fi
- echo shar: "extracting 'sys.c'" '(2672 characters)'
- if test -f 'sys.c'
- then
- echo shar: "will not over-write existing file 'sys.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'sys.c'
- X/*
- X** Cake system interface.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/sys.c,v 1.15 87/10/05 20:16:20 zs Exp $";
- X
- X#include "cake.h"
- X
- X/*
- X** Change to the directory of the cakefile.
- X** Return the shortened name of the cakefile.
- X*/
- X
- Xchar *
- Xdir_setup(name)
- Xreg char *name;
- X{
- X char buf[MAXSIZE];
- X reg int i, l; /* l is the subscript of the last / */
- X
- X l = -1;
- X for (i = 0; name[i] != '\0'; i++)
- X if (name[i] == '/')
- X l = i;
- X
- X if (l < 0)
- X return name;
- X else
- X {
- X for (i = 0; i < l; i++)
- X buf[i] = name[i];
- X
- X if (i == 0)
- X buf[i++] = '/';
- X
- X buf[i] = '\0';
- X if (chdir(buf) != 0)
- X {
- X sprintf(scratchbuf, "cake system error, chdir %s", buf);
- X perror(scratchbuf);
- X exit(1);
- X }
- X
- X return name+l+1;
- X }
- X}
- X
- X/*
- X** Set up the arguments to shell exec's.
- X** pattern: execl("/bin/sh", "sh", "-c", s, 0);
- X** pattern: execl("/bin/csh", "csh", "-cf", s, 0);
- X*/
- X
- Xchar *shell_path[2];
- Xchar *shell_cmd[2];
- Xchar *shell_opt[2];
- X
- Xshell_setup(shell, which)
- Xreg char *shell;
- Xreg int which;
- X{
- X char buf[MAXSIZE];
- X reg char *s;
- X reg int i, l;
- X
- X /* find the shell path */
- X i = 0;
- X for (s = shell; *s != '\0' && *s != ' ' && *s != '\t'; s++)
- X buf[i++] = *s;
- X
- X buf[i] = '\0';
- X shell_path[which] = new_name(buf);
- X
- X for (; *s != '\0' && *s != '-'; s++)
- X ;
- X
- X /* find the options */
- X i = 0;
- X for (; *s != '\0' && *s != ' ' && *s != '\t'; s++)
- X buf[i++] = *s;
- X
- X buf[i] = '\0';
- X if (i != 0)
- X shell_opt[which] = new_name(buf);
- X else
- X shell_opt[which] = NULL;
- X
- X if (*s != NULL)
- X {
- X fprintf(stderr, "cake: cannot parse shell command '%s'\n", shell);
- X exit_cake(FALSE);
- X }
- X
- X /* find the shell command itself */
- X s = shell_path[which];
- X l = -1;
- X for (i = 0; s[i] != '\0'; i++)
- X if (s[i] == '/')
- X l = i;
- X
- X shell_cmd[which] = new_name(s+l+1);
- X
- X if (cakedebug)
- X {
- X printf("shell path%d: %s\n", which, shell_path[which]);
- X printf("shell cmd%d: %s\n", which, shell_cmd[which]);
- X if (shell_opt[which] != NULL)
- X printf("shell opt%d: %s\n", which, shell_opt[which]);
- X else
- X printf("shell opt%d: NULL\n", which);
- X }
- X}
- X
- Xbool metatab[CHARSETSIZE];
- X
- X/*
- X** Set up the metacharacter table.
- X*/
- X
- Xmeta_setup(metachars)
- Xreg char *metachars;
- X{
- X reg int i;
- X reg char *s;
- X
- X for (i = 0; i < CHARSETSIZE; i++)
- X metatab[i] = FALSE;
- X
- X for (s = metachars; *s != '\0'; s++)
- X metatab[*s] = TRUE;
- X}
- X
- X/*
- X** Decide whether the given string has metacharacters or not.
- X** The second arg tells whether to honour backslash escapes.
- X*/
- X
- Xbool
- Xhas_meta(str, allow_esc)
- Xreg char *str;
- Xreg bool allow_esc;
- X{
- X reg char *s;
- X
- X for (s = str; *s != '\0'; s++)
- X if (metatab[(unsigned) *s])
- X return TRUE;
- X or (allow_esc && (*s == '\\'))
- X {
- X if (s[1] != '\0')
- X s++;
- X }
- X
- X return FALSE;
- X}
- SHAR_EOF
- if test 2672 -ne "`wc -c < 'sys.c'`"
- then
- echo shar: "error transmitting 'sys.c'" '(should have been 2672 characters)'
- fi
- fi
- echo shar: "extracting 'table.c'" '(2269 characters)'
- if test -f 'table.c'
- then
- echo shar: "will not over-write existing file 'table.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'table.c'
- X/*
- X** Table handling module.
- X**
- X** This file supplies data manipulation routines to other modules;
- X** it does not store any data itself. Its routines are generic,
- X** applicable to the storage of any kind of data structure with
- X** primary key and a hash function on it.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/table.c,v 1.15 87/10/05 20:16:28 zs Exp $";
- X
- X#include "cake.h"
- X
- X/*
- X** Initialize a table.
- X*/
- X
- X_init_table(table)
- Xreg Table *table;
- X{
- X reg int i;
- X
- X table->ta_store = make_many(List *, table->ta_size);
- X for (i = 0; i < table->ta_size; i++)
- X table->ta_store[i] = NULL;
- X}
- X
- X/*
- X** Look up and return the entry corresponding to the key
- X** in a table.
- X*/
- X
- XCast
- X_lookup_table(table, key)
- Xreg Table *table;
- Xreg Cast key;
- X{
- X reg List *ptr;
- X reg int h;
- X
- X put_trail("lookup_table", "start");
- X h = tablehash(table)(key);
- X for_list (ptr, table->ta_store[h])
- X {
- X if (tableequal(table)(key, tablekey(table)(ldata(ptr))))
- X {
- X#ifdef EXTRACHECK
- X if (ldata(ptr) == NULL)
- X {
- X fprintf(stderr, "cake internal error: returning null in lookup_table\n");
- X exit_cake(TRUE);
- X }
- X#endif
- X put_trail("lookup_table", "finish");
- X return ldata(ptr);
- X }
- X }
- X
- X put_trail("lookup_table", "finish");
- X return NULL;
- X}
- X
- X/*
- X** Insert a new entry into the table.
- X** Return whether it was there before.
- X*/
- X
- Xbool
- X_insert_table(table, entry)
- Xreg Table *table;
- Xreg Cast entry;
- X{
- X reg List *ptr;
- X reg Cast key;
- X reg int h;
- X
- X put_trail("insert_table", "start");
- X key = tablekey(table)(entry);
- X h = tablehash(table)(key);
- X for_list (ptr, table->ta_store[h])
- X if (tableequal(table)(key, tablekey(table)(ldata(ptr))))
- X {
- X put_trail("insert_table", "finish");
- X return TRUE;
- X }
- X
- X table->ta_store[h] = addhead(table->ta_store[h], entry);
- X put_trail("insert_table", "finish");
- X return FALSE;
- X}
- X
- X/*
- X** Hash str into the range 0 to SIZE-1.
- X*/
- X
- Xint
- Xhash(s)
- Xreg char *s;
- X{
- X reg int h;
- X
- X for (h = 0; *s != '\0'; s++)
- X h = (h << 1) + *s;
- X
- X return (h >= 0? h: -h) % SIZE;
- X}
- X
- X/*
- X** Return a list of all the entries in a table.
- X*/
- X
- XList *
- X_contents_table(table)
- Xreg Table *table;
- X{
- X reg List *all;
- X reg List *ptr;
- X reg int i;
- X
- X all = makelist0();
- X for (i = 0; i < table->ta_size; i++)
- X for_list (ptr, table->ta_store[i])
- X addtail(all, ldata(ptr)); /* na */
- X
- X return all;
- X}
- SHAR_EOF
- if test 2269 -ne "`wc -c < 'table.c'`"
- then
- echo shar: "error transmitting 'table.c'" '(should have been 2269 characters)'
- fi
- fi
- echo shar: "extracting 'test.c'" '(3874 characters)'
- if test -f 'test.c'
- then
- echo shar: "will not over-write existing file 'test.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'test.c'
- X/*
- X** Module to handle Cake's tests.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/test.c,v 1.15 87/10/05 20:16:34 zs Exp $";
- X
- X#include "cake.h"
- X
- Xbool
- Xeval(node, test, env)
- Xreg Node *node;
- Xreg Test *test;
- XEnv env;
- X{
- X extern char *expand_cmds();
- X extern int cake_proc();
- X extern Wait cake_wait();
- X extern Node *chase();
- X extern bool get_stat();
- X extern bool exist();
- X extern char *ground();
- X char buf[256];
- X Wait status;
- X reg List *ptr;
- X reg Pat *pat;
- X reg char *text1, *text2;
- X reg char *cmd;
- X reg Node *chasenode;
- X reg int result;
- X reg int pid;
- X
- X if (test == (Test *) NULL)
- X return TRUE;
- X
- X#ifdef CAKEDEBUG
- X if (cakedebug)
- X {
- X printf("testing ");
- X print_test(test);
- X printf("\n");
- X }
- X#endif
- X
- X switch (test->t_kind)
- X {
- X
- Xwhen t_TRUE: return TRUE;
- Xwhen t_FALSE: return FALSE;
- Xwhen t_AND: return eval(node, test->t_left, env) && eval(node, test->t_right, env);
- Xwhen t_OR: return eval(node, test->t_left, env) || eval(node, test->t_right, env);
- Xwhen t_NOT: return ! eval(node, test->t_left, env);
- X
- Xwhen t_CMD: if (get_stat(test->t_cmd, &status.w_status))
- X {
- X test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
- X cdebug("test cmd cache %s: %s\n", test->t_cmd,
- X (status.w_status == 0)? "True": "False");
- X return (status.w_status == 0)? TRUE: FALSE;
- X }
- X
- X cmd = expand_cmds(ground(env, test->t_cmd));
- X pid = cake_proc(cmd, Exec, "/dev/null", (Node *) NULL,
- X (int (*)()) NULL, (List *) NULL);
- X status = cake_wait(pid);
- X new_stat(test->t_cmd, status.w_status);
- X test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
- X cdebug("test cmd %s: %s\n", test->t_cmd,
- X (status.w_status == 0)? "True": "False");
- X return (status.w_status == 0)? TRUE: FALSE;
- X
- Xwhen t_MATCH: text1 = (char *) first(test->t_list); /* -vX */
- X text2 = (char *) last(test->t_list); /* file */
- X /* e.g. sub -vX X.c NULL file.c */
- X sprintf(buf, "sub %s %s NULL %s > /dev/null",
- X text1, text2, test->t_pat->p_str);
- X
- X cmd = new_name(buf);
- X cdebug("matching command: %s\n", cmd);
- X if (get_stat(cmd, &status.w_status))
- X {
- X test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
- X cdebug("test cmd cache %s: %s\n", test->t_cmd,
- X (status.w_status == 0)? "True": "False");
- X return (status.w_status == 0)? TRUE: FALSE;
- X }
- X
- X pid = cake_proc(cmd, Exec, "/dev/null", (Node *) NULL,
- X (int (*)()) NULL, (List *) NULL);
- X status = cake_wait(pid);
- X new_stat(test->t_cmd, status.w_status);
- X test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
- X cdebug("test cmd %s: %s\n", test->t_cmd,
- X (status.w_status == 0)? "True": "False");
- X return (status.w_status == 0)? TRUE: FALSE;
- X
- Xwhen t_LIST: for_list (ptr, test->t_list)
- X {
- X pat = (Pat *) ldata(ptr);
- X if (streq(test->t_pat->p_str, pat->p_str))
- X return TRUE;
- X }
- X
- X return FALSE;
- X
- Xwhen t_EXIST: result = exist(test->t_pat->p_str);
- X cdebug("test exist %s: %s\n", test->t_pat->p_str,
- X result? "True": "False");
- X return result;
- X
- Xwhen t_CANDO: chasenode = chase(test->t_pat->p_str, 0, (Entry *) NULL);
- X if (on_node(chasenode, nf_ERR))
- X {
- X sprintf(scratchbuf, "cannot evaluate 'cando %s' test for %s",
- X chasenode->n_name, node->n_name);
- X add_error(node, new_name(scratchbuf), LNULL, TRUE);
- X }
- X
- X result = is_ok(chasenode) || is_cando(chasenode);
- X cdebug("test cando %s: %s\n", test->t_pat->p_str,
- X result? "True": "False");
- X return result;
- X
- Xwhen t_OK: chasenode = chase(test->t_pat->p_str, 0, (Entry *) NULL);
- X if (on_node(chasenode, nf_ERR))
- X {
- X sprintf(scratchbuf, "cannot evaluate 'ok %s' test for %s",
- X chasenode->n_name, node->n_name);
- X add_error(node, new_name(scratchbuf), LNULL, TRUE);
- X }
- X
- X result = is_ok(chasenode);
- X cdebug("test ok %s: %s\n", test->t_pat->p_str,
- X result? "True": "False");
- X return result;
- X
- Xotherwise: fprintf(stderr, "cake internal error: invalid test type %x in eval\n",
- X test->t_kind);
- X exit_cake(TRUE);
- X }
- X
- X /*NOTREACHED*/
- X return FALSE;
- X}
- SHAR_EOF
- if test 3874 -ne "`wc -c < 'test.c'`"
- then
- echo shar: "error transmitting 'test.c'" '(should have been 3874 characters)'
- fi
- fi
- echo shar: "extracting 'trail.c'" '(1045 characters)'
- if test -f 'trail.c'
- then
- echo shar: "will not over-write existing file 'trail.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'trail.c'
- X/*
- X** Trail module.
- X*/
- X
- Xstatic char
- Xrcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/trail.c,v 1.14 86/07/19 12:24:19 zs Exp $";
- X
- X#ifdef CAKEDEBUG
- X#include "cake.h"
- X
- X#define TRAILSIZE 100
- X
- Xstatic int trail_entries = 0; /* no. of calls to put_tr */
- Xstatic int slot = 0; /* next slot */
- Xstatic char *trailfunc[TRAILSIZE]; /* functions and events */
- Xstatic char *trailevent[TRAILSIZE]; /* init to NULL by C */
- X
- X/*
- X** Register this function on the trail.
- X*/
- X
- Xput_trail(func, event)
- Xreg char *func;
- Xreg char *event;
- X{
- X trailfunc[slot] = func;
- X trailevent[slot] = event;
- X
- X trail_entries++;
- X if (++slot == TRAILSIZE)
- X slot = 0;
- X}
- X
- X/*
- X** Print the trail on the given file.
- X*/
- X
- Xget_trail(fp)
- Xreg FILE *fp;
- X{
- X reg int maxent;
- X
- X fprintf(fp, "^^^^^^^^^^^^^^^^^^^ TRAIL ^^^^^^^^^^^^^^^^^^^\n");
- X fprintf(fp, "%d entries\n", trail_entries);
- X
- X maxent = (trail_entries < TRAILSIZE)? trail_entries: TRAILSIZE;
- X while (maxent-- > 0)
- X {
- X if (--slot == -1)
- X slot = TRAILSIZE - 1;
- X
- X fprintf(fp, "%s %s\n", trailfunc[slot], trailevent[slot]);
- X }
- X}
- X#endif
- SHAR_EOF
- if test 1045 -ne "`wc -c < 'trail.c'`"
- then
- echo shar: "error transmitting 'trail.c'" '(should have been 1045 characters)'
- fi
- fi
- exit 0
- # End of shell archive
-